home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
-
- # ======================================================================
- # WebMonitor Standalone Module: mail
- #
- # CGI script for providing form and script
- # to send mail to configured system users
- #
- # required files: mail.list
- # Text file with users nicknames and
- # email addresses in the format of
- # <nickname>:<email address>
- # Keep "mail.list" in same directory as mail script
- # NOTE: you can even have group aliases!
- # just separate the addresses with commas
- # Make sure you 'chmod 0644 mail.list' so the server can read it
- # +-----------------------------------------
- # Example: |webmaster:admin@machine
- # |john-doe:jdoe
- # |carlos:cpero@ncsa.uiuc.edu
- # |group:leader@domain.com,member@domain.com
- # +-----------------------------------------
- # ======================================================================
- # Carlos A. Pero (cpero@ncsa.uiuc.edu) last update 10/17/95
- # ======================================================================
- # Documentation for WebMonitor can be found at
- # <URL:http://hoohoo.ncsa.uiuc.edu/webmonitor/>
- # ======================================================================
- # This code is in the public domain. Specifically, we give to the public
- # domain all rights for future licensing of the source code, all resale
- # rights, and all publishing rights.
- #
- # We ask, but do not require, that the following message be included in
- # all derived works:
- #
- # Portions developed at the National Center for Supercomputing
- # Applications at the University of Illinois at Urbana-Champaign.
- #
- #
- # THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED,
- # FOR THE SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT
- # LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A
- # PARTICULAR PURPOSE.
- # ======================================================================
- # For the greatest security, this script relies on a 'mail.list' file
- # with a list of authorized nicknames and email address which can receive
- # email through this mail script.
- #
- # For greater scalability, the '@AUTHDOMAINS' array can be used to store
- # a list of domains. Any email address ending with one of these domains
- # can use this script to receive email. In this case, the full email
- # address becomes the 'nickname'.
- # ======================================================================
- # This script can be referenced 2 ways for the best flexibility:
- #
- # DIRECTLY, <A HREF="/cgi-bin/mail?nickname">
- # This will generate an email form for the person named in 'nickname',
- # and if they exist in the 'mail.list' file.
- # If no 'nickname' is specified in the QUERY_STRING when the script is
- # first invoked, or the nickname cannot be found in the 'mail.list',
- # an email form with a SELECT box of all valid nicknames is generated.
- # When the email form is submitted, it will call itself via method of POST,
- # and send the email to the recipient, outputting a confirmation message.
- # If the HTTP_REFERER was trasmitted when the script was first invoked,
- # there will be a hyperlink available to go back to that page (such as
- # the user's home page).
- #
- # FORWARDING RESULTS, <FORM METHOD="POST" ACTION="/cgi-bin/mail?nickname">
- # This will forward the results from the FORM, which can exist anywhere,
- # to the recipient specified by 'nickname'. Since the 'nickname' is in
- # the QUERY_STRING, the FORM *must* use the METHOD="POST", otherwise the
- # recipient's nickname will be blown away.
- # Users may want to include a:
- # <INPUT TYPE="hidden" NAME="next-url" VALUE="/~user/received.html">
- # If this is present in the FORM input, the client will be redirected
- # to this HTML file as a confirmation message instead of the default.
- # In addition, the user can also define any of the following input names
- # in their form to better customize the output mailed back to them.
- # <INPUT TYPE="hidden" NAME="subject" VALUE="My survey results">
- # <INPUT TYPE="hidden" NAME="from-name" VALUE="Average Web user">
- # <INPUT TYPE="hidden" NAME="from-email" VALUE="jdoe@domain.com">
- # These values will then be used in the header of the email message.
- # Otherwise, default values will be substituted.
- # ======================================================================
-
-
- ########################################################################
- ########## Configurable variables ######################################
-
- $SENDMAIL = '/usr/lib/sendmail';
- # The location of your sendmail binary
-
- @AUTHDOMAINS = ('');
- # List of lower-case Internet domains that can use this script
- # such as ('ncsa.uiuc.edu', 'domain.com')
-
- ## Also, make sure the first line of this script points
- ## to your PERL binary
-
- ########## Nothing else to change ######################################
- ########################################################################
-
-
- $ENV{'SCRIPT_NAME'} =~ m#(/.*/)(.*)$#;
- $SCRIPTDIR = $1;
- $SCRIPT = $2;
-
- #### Do standard HTTP stuff ####
- &cgi_receive;
- &cgi_decode;
- &cgi_header;
-
- #### Load mail.list into associative array ####
- open (MAILNAMES, "mail.list") || die ("$SCRIPT: Can't open mail.list: $!\n");
- while (<MAILNAMES>) {
- chop;
- ($nick, $addr) = split(/:/, $_);
- $ADDRESS{$nick} = $addr;
- }
- close (MAILNAMES);
-
- #### Figure out who the information should be sent to ####
- if ($ENV{'QUERY_STRING'} =~ /\@/) {
- #### User specified a full email address ####
- ($machine = $') =~ tr/A-Z/a-z/;
- undef $FLAG{'authorized'};
- for ($[ .. $#AUTHDOMAINS) {
- $FLAG{'authorized'} = $AUTHDOMAINS[$_], last if ($ENV{'QUERY_STRING'} =~ /$AUTHDOMAINS[$_]$/);
- }
- &error_blank_field('an authorized email address') unless ($FLAG{'authorized'});
- $recipient = $ENV{'QUERY_STRING'};
- $extraaction = "?$recipient";
- }
- elsif ($ENV{'QUERY_STRING'}) {
- #### User specified a nickname ####
- $nickname = $ENV{'QUERY_STRING'};
- &error_blank_field('a valid recipient nickname') unless ($ADDRESS{$nickname});
- $recipient = $ADDRESS{$nickname};
- $extraaction = "?$nickname";
- }
- elsif ($FORM{'nickname'}) {
- #### Input is coming from listbox, ready for forwarding ####
- $nickname = $FORM{'nickname'};
- &error_blank_field('a valid recipient nickname') unless ($ADDRESS{$nickname});
- $recipient = $ADDRESS{$FORM{'nickname'}};
- }
- elsif ($ENV{'REQUEST_METHOD'} eq "POST") {
- #### I don't know who the information was for ####
- &error_blank_field('a valid recipient');
- }
-
- #### Output a default email form if not POSTing already ####
- &print_form unless ($ENV{'REQUEST_METHOD'} eq "POST");
-
- #### Check for require fields
- foreach $field (@requirefields) {
- &error_blank_field($field) unless ($FORM{$field});
- }
-
- #### Fill in missing fields for forwarding FORM results ####
- ($FORM{'subject'}) || ($FORM{'subject'} = "FORM results");
- ($FORM{'from-email'}) || ($FORM{'from-email'} = $recipient);
- ($FORM{'from-name'}) || ($FORM{'from-name'} = "WebMonitor mail");
-
- open (MAIL, "| $SENDMAIL $recipient") || die ("$SCRIPT: Can't open $mailprog: $!\n");
- print MAIL "Reply-to: $FORM{'from-email'} ($FORM{'from-name'})\n";
- print MAIL "From: $FORM{'from-email'} ($FORM{'from-name'})\n";
- print MAIL "To: $recipient\n";
- print MAIL "Subject: $FORM{'subject'}\n";
- print MAIL "X-Comments: =============================================================\n";
- print MAIL "X-Comments: NOTE: This message was sent through the WebMonitor mail form\n";
- print MAIL "X-Comments: =============================================================\n";
- print MAIL "X-Comments: HOST: $ENV{'REMOTE_HOST'} ($ENV{'REMOTE_ADDR'})\n";
- print MAIL "X-Comments: BROWSER: $ENV{'HTTP_USER_AGENT'}\n";
- print MAIL "X-Comments: REFERER: $FORM{'previous-url'}\n" if ($FORM{'previous-url'});
- print MAIL "X-Comments: =============================================================\n";
- print MAIL "\n";
- &dump_values(FORM, MAIL);
- print MAIL "\n";
- close (MAIL);
-
- #### Now, redirect if "next-url" is included
- if ($FORM{'next-url'}) {
- print "Location: $FORM{'next-url'}\n";
- print "\n";
- exit;
- }
-
- #### Prevent HTML output
- foreach $key (keys %FORM) {
- $FORM{$key} =~ s/</\</g;
- $FORM{$key} =~ s/>/\>/g;
- }
-
- #### Output confirmation message ####
- print qq|<HTML><HEAD><TITLE>WebMonitor-Email Sent</TITLE></HEAD><BODY>\n|;
- print qq|<H1>$ENV{'SERVER_NAME'} Email Sent</H1>\n|;
- print qq|The following message has been sent.\n|;
- print qq|You can now return to <A HREF="$FORM{'previous-url'}">where you were</A>.\n| if ($FORM{'previous-url'});
- print qq|<HR>\n|;
- print "<PRE>\n";
- print "Reply-to: $FORM{'from-email'} ($FORM{'from-name'})\n";
- print "From: $FORM{'from-email'} ($FORM{'from-name'})\n";
- print "To: $recipient\n";
- print "Subject: $FORM{'subject'}\n";
- print "\n";
- &dump_values(FORM, STDOUT);
- print "\n";
- print "</PRE>\n";
- print "</BODY></HTML>\n";
- exit;
-
- #####################################################################
- #### SUBROUTINES ####################################################
-
- sub error_blank_field {
- local($variable) = @_;
- print "\n" if ($FORM{'next-url'});
- print "<HTML><HEAD><TITLE>WebMonitor-Email Error</TITLE></HEAD><BODY>\n";
- print "<H1>Error!</H1>\n";
- print "You did not fill in $variable.\n";
- print "</BODY></HTML>\n";
- exit;
- }
-
- sub cgi_header {
- print "Content-type: text/html\n";
- print "\n" unless ($FORM{'next-url'});
- }
-
- sub cgi_receive {
- if ($ENV{'REQUEST_METHOD'} eq "POST") {
- read(STDIN, $incoming, $ENV{'CONTENT_LENGTH'});
- }
- else {
- $incoming = $ENV{'QUERY_STRING'};
- }
- }
-
- sub cgi_decode {
- @pairs = split(/&/, $incoming);
-
- foreach (@pairs) {
- ($name, $value) = split(/=/, $_);
-
- $name =~ tr/+/ /;
- $value =~ tr/+/ /;
- $name =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/gie;
- $value =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/gie;
-
- #### Strip out semicolons unless for special character
- $value =~ s/;/$$/g;
- $value =~ s/&(\S{1,6})$$/&\1;/g;
- $value =~ s/$$/ /g;
-
- $value =~ s/\|/ /g;
- $value =~ s/^!/ /g; ## Allow exclamation points in sentences
-
- #### Split apart any directive prefixes
- #### NOTE: colons are reserved to delimit these prefixes
- @parts = split(/:/, $name);
- $name = $parts[$#parts];
- if (grep(/^require$/, @parts)) {
- push (@requirefields, $name);
- }
- if (grep(/^ignore$/, @parts)) {
- push (@ignorefields, $name);
- }
- if (grep(/^dynamic$/, @parts)) {
- #### For simulating a checkbox
- #### It may be dynamic, but useless if nothing entered
- next if ($value eq "");
- $name = $value;
- $value = "on";
- }
-
- #### Skip generally blank fields
- next if ($value eq "");
-
- #### Allow for multiple values of a single name
- $FORM{$name} .= ", " if ($FORM{$name});
-
- $FORM{$name} .= $value;
- #### Add to ordered list if not on list already
- push (@fields, $name) unless (grep(/^$name$/, @fields));
- }
- }
-
- sub dump_values {
- local($env, $handle) = @_;
- ($handle eq "STDOUT") && (print $handle "<PRE>\n");
- foreach $field (@fields) {
- next if (grep(/^$field$/, @ignorefields));
- if ($FORM{$field} =~ /[\cM\n]/) {
- print $handle "($field)\n";
- print $handle "-" x 75, "\n", $FORM{$field}, "\n", "-" x 75, "\n";
- }
- else {
- print $handle "($field) $FORM{$field}\n";
- }
- }
- ($handle eq "STDOUT") && (print $handle "</PRE>\n");
- }
-
- sub print_form {
- print qq|<HTML><HEAD><TITLE>WebMonitor-Email Form</TITLE></HEAD><BODY>\n|;
- print qq|<H1>$ENV{'SERVER_NAME'} <A HREF="http://hoohoo.ncsa.uiuc.edu/webmonitor/module-mail.html">Email Form</A></H1>\n|;
- print qq|<FORM METHOD="POST" ACTION="$ENV{'SCRIPT_NAME'}$extraaction">\n|;
- print qq|<HR>\n|;
- print qq|<INPUT TYPE="submit" VALUE="Send Email"> to |;
-
- if ($nickname) {
- print qq|<I>$recipient</I> <B>($nickname)</B>\n|;
- }
- elsif ($recipient) {
- print qq|<I>$recipient</I>\n|;
- }
- else {
- print qq|<SELECT NAME="ignore:nickname">\n|;
- print qq|<OPTION>Select name...\n|;
- foreach $nick (sort keys %ADDRESS) {
- print qq|<OPTION>$nick\n|;
- }
- print qq|</SELECT>\n|;
- }
-
-
- print qq|<HR>\n|;
- print qq|<PRE>|;
- print qq| Your Name: <INPUT NAME="require:ignore:from-name" SIZE="30">\n|;
- print qq|Email Address: <INPUT NAME="require:ignore:from-email" SIZE="30">\n|;
- print qq| Subject: <INPUT NAME="ignore:require:subject" SIZE="40"> <INPUT TYPE="reset" VALUE="Clear Message">\n|;
- print qq|</PRE>\n|;
- print qq|<TEXTAREA NAME="require:message" ROWS="15" COLS="75"></TEXTAREA>\n|;
- print qq|<INPUT TYPE="hidden" NAME="ignore:previous-url" VALUE="$ENV{'HTTP_REFERER'}">\n|;
- print qq|</FORM>\n|;
- print qq|</BODY></HTML>\n|;
-
- exit;
- }
-
-